package com.gitee.melin.bee.core.conf;

import java.util.Set;
import java.util.function.Function;
import org.apache.commons.lang3.StringUtils;

/**
 * @author melin
 */
public class TypedConfigBuilder<T> {

    private ConfigBuilder parent;

    private Set<T> validValues;

    private ConfigEntry<T> configEntry;

    public TypedConfigBuilder(ConfigBuilder parent) {
        this.parent = parent;
    }

    /** Check that user-provided values for the config match a pre-defined set. */
    public TypedConfigBuilder<T> checkValues(Set<T> values) {
        this.validValues = values;
        return this;
    }

    public ConfigEntry<T> createWithDefault(T defaultValue) {
        configEntry = new ConfigEntry<T>(parent.getKey(), parent.getDoc(), parent.getVersion(), defaultValue);

        if (validValues != null && !validValues.contains(defaultValue)) {
            throw new IllegalArgumentException("The value of "
                    + parent.getKey()
                    + " should be one of "
                    + StringUtils.join(validValues, ", ")
                    + ", but was "
                    + defaultValue);
        }
        configEntry.setValidValues(this.validValues);
        return configEntry;
    }

    public ConfigEntry<T> create() {
        configEntry = new ConfigEntry<T>(parent.getKey(), parent.getDoc(), parent.getVersion());
        return configEntry;
    }

    public ConfigEntry<T> checkValue(Function<T, Boolean> validator, String errorMsg) {
        T value = configEntry.getDefaultValue();
        if (!validator.apply(value)) {
            throw new IllegalArgumentException(value + " in " + configEntry.getKey() + " is invalid. " + errorMsg);
        }

        return configEntry;
    }
}
